<?php
namespace Orx;
/**
 * Kpi Main Wrapper
 * 
 * A KPI is an indicator define by a 
 * 
 * 
 * 
 * @author 	Xavier VILAIN
 * @package Orx
 * @license #license-orx#
 * 
 * @property int 		$kpiid			Id of the KPI
 * @property string 	$language		Language
 * @property string 	$label			Label
 * @property string 	$description	Description
 * @property decimal 	$threshold		Threshold
 * @property decimal 	$target			Target
 * @property bool 		$active			Is active 
 * @property bool 		$standard		Is a standard KPI (can not be deleted)
 * @property int 		$periodicity	Periodicity (Day,Week,Month or Year)
 * @property bool 		$in_widget		Can be display has a widget in the dashboard
 */
use Fox\Generator;

class Kpi extends \Fox\Object\Customizing {
	
	/**
	 * 
	 * Decoded Params
	 * @var array
	 */
	protected $decodedParams;
	
	/**
	 * KPIs reverse link
	 * @var string
	 */
	const LINK_KPIS = 'kpis';
	
	/**
	 * KPI reverse link
	 * @var string
	 */
	const LINK_KPI = 'kpi';
		
	/**
	 * Link to category
	 * @var string
	 */
	const LINK_CATEGORY = 'category';
	
	/**
	 * Link to Targets
	 * @var string
	 */
	const LINK_TARGETS = 'targets';
	
	/**
	 * Link to periodicity
	 * @var string
	 */
	const LINK_PERIODICITY = 'periodicity';
	
	/**
	 * Render as a progress bar
	 * @var string
	 */
	const RENDER_PROGRESS_BAR = 'pg';

	/**
	 * Link to User preferences
	 * @var string
	 */
	const LINK_USER_PREFERENCES = 'userPreferences';
	
	/**
	 * 
	 * Render Grid
	 * @var string
	 */
	const RENDER_GRID = null;
	
	/**
	 * Return translated descriptoin
	 * @return string
	 */
	public function description() {
		return $this->i18nParse('description');
	}
	
	/**
	 * 
	 * Decode Params
	 * @return array
	 */
	public function params() {
		if(empty($this->decodedParams)) {
			$this->decodedParams = json_decode($this->params,true);
		}
		return $this->decodedParams;
	}
	
	/**
	 * Find Default Current Period Base on Periodicity
	 * @return string
	 */
	public function currentPeriod() {
		$today =  new \DateTime();
		switch ($this->periodicity) {
			case Kpi\Periodicity::DAY :
				$start = new \DateTime();
				break;
			case Kpi\Periodicity::WEEK :
				$timestamp = \Fox\Utilities\Dates::firstWeekDay(time());
				$start = new \DateTime($timestamp);
				break;
			case Kpi\Periodicity::MONTH :
				$start = new \DateTime($today->format('Y-m').'-01');
				break;
			case Kpi\Periodicity::YEAR :
				$start = new \DateTime($today->format('Y').'-01-01');
				break;
		}
		return $start->format('Y-m-d');
	}
	
	/**
	 * 
	 * Run KPI to retrieve Data 
	 * 
	 */
	public function run($inputs = null) {
		// Decode Query Params
		$params = $this->params();
		// 
		$db = \Fox\Databases::databases()->handle(\Fox\Databases::DB_APP);
		$sql = 'SELECT '.$params['select'].' ';
		$sql .= 'FROM '.$params['from'].' ';
		$sql .= 'WHERE '.$params['where'].' ';
		
		$periodFieldName = empty($params['period_fieldname']) ? null : $params['period_fieldname'];
		$authorFieldName = empty($params['author_fieldname']) ? null : $params['author_fieldname'];
		// Additionnal where
		if(is_array($inputs)) {
			$i = 1;
			$first = empty($params['where']) ? '' : ' AND ';
			foreach($inputs as $fieldname => $value) {
				
				if(empty($value)) {
					continue;
				}
				if($fieldname == 'author') {
					$fieldname = $authorFieldName;
				}
				if(is_array($value)) {
					$sql .= "$first $fieldname IN(?) ";
				} elseif($fieldname == 'period_left') {
					if(empty($periodFieldName)) {
						continue;
					}
					$sql .= "$first $periodFieldName >= ? ";
				} elseif($fieldname == 'period_right') {
					if(empty($periodFieldName)) {
						continue;
					}
 					$sql .= "$first $periodFieldName < ? ";
				} else{
					$sql .= "$first $fieldname = ? ";
				}
				$first = 'AND ';
				$valueToBind[$i] = $value;
				$i++;
			}

		}
		if(!empty($params['group_by'])) {
			$sql .='GROUP BY '.$params['group_by'];
		}
		if(!empty($params['order_by'])) {
			$sql .='GROUP BY '.$params['order_by'];
		}
		
		$kpiQuery = $db->prepare($sql);
		if(isset($valueToBind)) {
			foreach($valueToBind as $index => $value) {
				$kpiQuery->bindValue($index,$value);
			}
		}
		
		$kpiQuery->execute();
		$data = $kpiQuery->fetchAll(\PDO::FETCH_ASSOC);
		return $data;
	}
	
	/**
	 * 
	 * Output the indicator in the selected mode.
	 * By default it display a data grid
	 * @param string $mode
	 */
	public function render($mode = null,$data,$multiple = false) {
		if(!is_array($data)) {
			return null;
		}
		switch ($mode) {
			case 'pg' :
				foreach($data as $item) {
					$output[] = new \Fox\Html\Bar\Progress($item['author'],
									 					$this->threshold, 
									 					$this->target, 
									 					$this->scale,
									 					$item['indicator'], 
									 					$this->label());
				}
				return $output;
			default:
				$grid = new \Fox\Grid('kpi');
				$grid->fieldcat(array('author','indicator'));
				$grid->fieldcat()->setGenerators(array(
					'author' => \Fox\Generator::useFunction(function($data) {
						return \Fox\User::fullName($data['author']);
					})
				));
				$grid->fieldcat()->field('indicator')
						->label($this->label());
						
				$grid->initialize($data);
				return $grid;
			break;
		}
	}
}
\Fox\Dao::infos(Kpi::className(),new \Fox\Object\Info('kpis', \Fox\Databases::DB_APP));

// Link To I18n
\Fox\Object\Links::add(\Fox\Dao::link(Kpi\I18n::className(), Kpi\I18n::LINK_TO_PARENT)
->to(Kpi::className(), Kpi::LINK_I18N)
->on('kpiid')
->versionFrom());

// Link To Targets
\Fox\Object\Links::add(\Fox\Dao::link(Kpi\Target::className(), Kpi::LINK_KPI)
->to(Kpi::className(), Kpi::LINK_TARGETS)
->on('kpiid')
->versionFrom());

// Link To Category
\Fox\Object\Links::add(\Fox\Dao::link(Kpi\Category::className(),Kpi::LINK_KPIS)
->to(Kpi::className(), Kpi::LINK_CATEGORY)
->on('category')
->oneToOne());

// Link To Periodicity
\Fox\Object\Links::add(\Fox\Dao::link(Kpi\Periodicity::className(),Kpi::LINK_KPIS)
->to(Kpi::className(), Kpi::LINK_PERIODICITY)
->on('periodicity')
->oneToOne());

// Link To Periodicity
\Fox\Object\Links::add(\Fox\Dao::link(Kpi\User\Preference::className(),Kpi::LINK_KPIS)
->to(Kpi::className(), Kpi::LINK_USER_PREFERENCES)
->on('kpiid'));